package jmind.core.support;

import jmind.base.lang.Pair;
import jmind.base.util.DataUtil;
import jmind.base.util.GlobalConstants;
import jmind.core.http.HttpClient;
import jmind.core.log.LogUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;

/**
 * http://xiaoa7.iteye.com/blog/1262034
 * @author xieweibo
 * @date 2015年7月9日
 */

public class HttpUtil {
    private static final Logger logger = LogUtil.getLogger(HttpUtil.class);
    private static final HttpClient client = HttpClient.getHttpClient();

    public static void main(String[] args) throws IOException {
        String url="https://list.jd.com/list.html?cat=9192%2C14203%2C14204&page=1&s=1&click=0";
        // url="https://search.jd.com/Search?keyword=%E8%8D%AF%E5%93%81&enc=utf-8&wq=%E8%8D%AF%E5%93%81&pvid=ce5fd366a6a54dcbb6adc725860d836c";
        System.err.println(HttpUtil.fliggyGet(url));
    }

    /**
     * 飞猪航旅代理抓取,防止单个ip受到限制
     * @param url
     * @return
     * @throws InterruptedException
     */
    public static String fliggyGet(String url) {
        CloseableHttpClient httpclient = null;
        try {
            if (url.startsWith("https")) {
                SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                    // 默认信任所有证书
                    @Override
                    public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                        return true;
                    }
                }).build();
                // AllowAllHostnameVerifier: 这种方式不对主机名进行验证，验证功能被关闭，是个空操作(域名验证)
                SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory(sslContext,
                        SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
                httpclient = HttpClients.custom().setSSLSocketFactory(sslcsf).build();
            } else {
                httpclient = HttpClients.createDefault();
            }

            HttpGet httpGet = new HttpGet(url);
            httpGet.addHeader("trpr-client-name", "alihealth-reserve");
            httpGet.addHeader("trpr-proxy-socket-timeout", "20000");
            //依次是代理地址，代理端口号，协议类型 使用https协议
            HttpHost proxy = null;
            proxy = new HttpHost("140.205.171.24", 80);
            RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
            httpGet.setConfig(config);
            //httpGet.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36");
            httpGet.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
            long start = System.currentTimeMillis();
            logger.info("HttpClientUtils|request begin|{}", url);
            CloseableHttpResponse response = httpclient.execute(httpGet);
            logger.info("HttpClientUtils|request end|{}|{}", System.currentTimeMillis() - start, url);
            HttpEntity entity = response.getEntity();
            String content = EntityUtils.toString(entity);
            EntityUtils.consume(entity);
            return content;
        } catch (Exception e) {
            logger.warn("HttpClientUtils|exception|{}", e);
        } finally {
            if (httpclient != null) {
                    try {
                        httpclient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }

        }
        return null;
    }

    /**
     * 发送HTTP请求
     * 
     * @param urlString
     * @return 响映对象
     * @throws IOException
     */
    public static String sendPost(String urlString, String content,Map<String,String> props) {
        long start = System.currentTimeMillis();
        HttpURLConnection urlConnection = null;
        String res = null;
        try {
            URL url = new URL(urlString);
            urlConnection = (HttpURLConnection) url.openConnection();
            if(!DataUtil.isEmpty(props)){
                for(Map.Entry<String,String> entry:props.entrySet()){
                    urlConnection.setRequestProperty(entry.getKey(),entry.getValue());
                }
            }
        //    urlConnection.setRequestProperty("Content-Type","application/json");
            urlConnection.setConnectTimeout(1000);
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            urlConnection.getOutputStream().write(content.getBytes("UTF-8"));
            urlConnection.getOutputStream().flush();
            urlConnection.getOutputStream().close();
            InputStream in = urlConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
            String line = bufferedReader.readLine();
            StringBuilder builder = new StringBuilder();
            while (line != null) {
                builder.append(line);
                line = bufferedReader.readLine();
            }
            res = builder.toString();
        } catch (Exception e) {
            logger.error(urlString, e);
        } finally {
            long t = System.currentTimeMillis() - start;
            String slow = t > HttpClient.SLOW_TIME ? "slow|" : "";
            logger.debug(slow + "t={},url={},res={}", t, urlString, res);
            if (urlConnection != null)
                urlConnection.disconnect();
        }

        return res;
    }

    /**
     *  HttpClient get
     * @param url
     * @return
     */
    public final static String get(String url) {
        return client.get(url, GlobalConstants.UTF8, 1000,null);
    }

    /**
     * 
     * @param url
     * @param code 编码默认 UTF-8
     * @param timeout 超时时间
     * @return
     */
    public final static String get(String url, final String code, int timeout) {
        return client.get(url, code, timeout,null);
    }

    public static String post(String url, Map<String, ?> params) {

        return client.post(url, params);
    }

    /**
     * 
     * @param url
     * @param params 参数不用map 是因为参数名可能重复
     * @return
     * @throws IOException
     */
    public static String post(String url, List<Pair<String, String>> params, String code) {
        return client.post(url, params, code, 0);

    }

    /**
     * 上传文件
     * @param url 请求url
     * @param params 参数
     * @param fileName file参数名
     * @param file 文件
     * @return
     */
    public static String postFile(String url, Map<String, ?> params, String fileName, File file) {
        return client.postFile(url, params, fileName, file, GlobalConstants.UTF8);
    }

}
